#include "../../../common/channel.hpp"
#include "../../../common/etcd.hpp"
#include <gflags/gflags.h>
#include <thread>
#include "main.pb.h"

#include "../../../common/logger.hpp"


DEFINE_bool(run_mode,false,"程序的运行模式，false： 调试 true： 发布");
DEFINE_string(log_file,"","发布模式下，向文件中输出，如果是调试模式下，模式是stdout");
DEFINE_int32(log_level,0,"发布模式下，用于指定的日志输出等级");

DEFINE_string(etcd_host, "http://127.0.0.1:2379", "服务注册中心地址");
DEFINE_string(base_service, "/service", "服务监控根目录");
DEFINE_string(call_service, "/service/echo", "服务监控根目录");


int main(int argc,char* argv[])
{
    google::ParseCommandLineFlags(&argc,&argv,true);
    init_logger(FLAGS_run_mode,FLAGS_log_file,FLAGS_log_level);

    //创建rpc管理对象
    auto sm = std::make_shared<ServiceManager>();
    //设置关心的事件
    sm->declared(FLAGS_call_service);
    auto put_cb = std::bind(&ServiceManager::onServiceOnline,sm.get(),std::placeholders::_1,std::placeholders::_2);
    auto del_cb = std::bind(&ServiceManager::onServiceOffline,sm.get(),std::placeholders::_1,std::placeholders::_2);

    //创建服务器对象
    Discovery::ptr dclient = std::make_shared<Discovery>(FLAGS_etcd_host,FLAGS_base_service,put_cb,del_cb);

    while(1) {
        //通过rpc通道管理对象，提供echo服务的通道
        auto channel = sm->choose(FLAGS_call_service);
        if(!channel) {
            std::this_thread::sleep_for(std::chrono::seconds(1));
            return -1; 
        }

        //发起rpc调用
        example::EchoService_Stub stub(channel.get());
        example::EchoRequest req;
        req.set_message("这是测试rpc的消息");
        brpc::Controller* cntl = new brpc::Controller();
        example::EchoResponse* rsp = new example::EchoResponse();
        stub.Echo(cntl,&req,rsp,nullptr);
        if (cntl->Failed() == true)
        {
            std::cout << "rpc调用失败： " << cntl->ErrorText() << std::endl;
            delete cntl;
            delete rsp;
            std::this_thread::sleep_for(std::chrono::seconds(1));
            continue;
        }

        
        std::cout << "收到响应：" << rsp->message() <<std::endl; 
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }

    return 0;
}